const fs = require('fs')
const apis = require('./api')

/**
 * @param startId                       第一章id
 * @param fileName                      文件名
 * @param chapterSliceNumber            每隔多少章节分割一次文件
 * @param endNumber                     请求多少章节停止
 * @param continuousErrorCloseNumber    连续错误关闭（次数）
 */

class WriteChapter {
  #url = 'https://www.mht99.com/17023' // 网站
  #pageIndex = 0 // 页码
  #fileIndex = 1 // 文件下标
  #finishChapterNumber = 0 // 已完成加载的数量
  #data = [] // 数据存放
  #continuousErrorNumber = 0 // 连续请求错误次数
  reg = /<div id="content">[\s\S]*10000/

  constructor(startId, fileName = '文章', chapterSliceNumber = 100, endNumber = 10000, continuousErrorCloseNumber = 5) {
    if (this.#aguTypeValidate(startId, endNumber, chapterSliceNumber, continuousErrorCloseNumber, fileName)) {
      this.chapterSliceNumber = chapterSliceNumber
      this.startId = startId
      this.fileName = fileName
      this.endNumber = endNumber
      this.continuousErrorCloseNumber = continuousErrorCloseNumber
    } else {
      console.error('错误：传入参数类型错误！\n 示例：new WriteChapter(13111, "西游记", 100, 1000, 5)')
    }
  }

  start() {
    this.#getPage().then(() => {
      this.start()
    })
  }

  #getPage() {
    return new Promise((resolve, reject) => {
      if (this.startId) {
        let id = this.#pageIndex === 0 ? this.startId : `${this.startId}_${this.#pageIndex}`

        apis.getPage(`${this.#url}/${id}.html`).then((res) => {
          const body = res.body

          if (body === 0) {
            this.#pageIndex = 0
            this.startId++
            this.#continuousErrorNumber++

            if (this.#continuousErrorNumber >= this.continuousErrorCloseNumber) {
              reject()
            } else {
              resolve()
            }
          } else {
            if (this.#finishChapterNumber >= this.endNumber) {
              this.#pushData(body)
              this.#write()
              this.#data = []
              reject()
              return
            }

            if (this.#finishChapterNumber !== 0 && this.#finishChapterNumber % this.chapterSliceNumber === 0) {
              this.#pushData(body)
              this.#write()
              this.#data = []
              // this.#pageIndex = 0
              // this.startId++
              // this.#finishChapterNumber++
              this.#fileIndex++
              resolve()
            } else {
              this.#pushData(body)
              this.#finishChapterNumber++
              this.#pageIndex++
              resolve()
            }
          }
        })
      }
    })
  }

  #pushData(res) {
    let str = this.reg.exec(res) && this.reg.exec(res)[0] ? this.reg.exec(res)[0] : ''

    if (this.#data && this.#data[0] && str === this.#data[this.#data.length - 1]) {
      this.#data.push(str)
      this.#finishChapterNumber++
      this.#pageIndex = 0
      this.startId++
      this.#continuousErrorNumber++
    } else {
      this.#continuousErrorNumber = 0
      this.#data.push(str)
    }
  }

  #write() {
    let fileFullName = `./assets/${this.fileName}_${this.#fileIndex}_${this.startId}.json`
    let data = this.#data
    let html = ''
    data.forEach((item) => {
      item = item
        .replace('<div id="content">', '')
        .replace('<p data-id="10000', '<br/>')
        .replace(/[，。？！]/g, '<br/>')
      html += item
    })
    let json = html.split('<br/>')
    fs.writeFile(fileFullName, JSON.stringify(json), (err) => {
      if (err) {
        console.error('-------', 'err: ', err)
      } else {
        console.log('-------', 'success: ', fileFullName)
      }
    })
  }

  #aguTypeValidate(startId, endNumber, chapterSliceNumber, continuousErrorCloseNumber, fileName) {
    let startIdV = !isNaN(Number(startId)),
      chapterSliceNumberV = !chapterSliceNumber || !isNaN(Number(chapterSliceNumber)),
      endNumberV = !endNumber || !isNaN(Number(endNumber)),
      continuousErrorCloseNumberV = !continuousErrorCloseNumber || !isNaN(Number(continuousErrorCloseNumber)),
      fileNameV = typeof fileName === 'string'

    return startIdV && chapterSliceNumberV && endNumberV && continuousErrorCloseNumberV && fileNameV
  }
}

module.exports = WriteChapter
